package model;

import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ConcurrentHashMap;

import utilities.Archive;
import utilities.ArchiveFactory;

import main.Log;
import utilities.*;

public class GameClock {

	private static GameClock instance;//used to implement the singleton pattern
	
	private long tickDurationMS = 25;
	private ConcurrentHashMap<Executable, TimerTask> executableToTimerTask;
	private Timer timer;
	
	
	private GameClock() {
		timer = new Timer();
		executableToTimerTask = new ConcurrentHashMap<Executable, TimerTask>();
	}
	
	public static GameClock getInstance() {
		if (instance != null) {
			return instance;
		}
		return instance = new GameClock();
	}
	
	public void schedule( long numberOfTicks, final Executable executable ) {
		TimerTask tt = new TimerTask() {
			@Override
			public void run() {
				executableToTimerTask.remove(executable);
				executable.execute();
			}
		};
		this.executableToTimerTask.put( executable, tt );
		try {
			timer.schedule( tt, numberOfTicks * tickDurationMS );
		} catch (Exception e ) {
			Log.out(Log.MODEL, "{EXCEPTION} in GameClock: " + e.getMessage() );
		}
	}
	
	public void scheduleAtFixedRate( long numberOfTicks, final Executable executable ) {
		TimerTask tt = new TimerTask() {
			@Override
			public void run() {
				executable.execute();
			}
		};
		this.executableToTimerTask.put( executable, tt );
		timer.scheduleAtFixedRate( tt, numberOfTicks * tickDurationMS, 
				numberOfTicks * tickDurationMS );
	}
	
	public void remove( Executable executable ) {
		//remove it from the map
		TimerTask tt = this.executableToTimerTask.remove(executable);
		if( tt == null ) { return ; }
		//and cancel it
		tt.cancel();
	}
	
}
